在現代的Web應用程式中,安全性是不可忽視的要素。Spring Security 是一個強大的框架,旨在為Java應用程式提供全面的安全性解決方案。在這篇文章中,我們將探討如何使用Spring Security來實現細緻的角色與權限管理
在安全性管理中,角色(Role)和權限(Permission)的區別非常重要:
角色:通常是與使用者相關聯的一組權限,代表了使用者的身份。例如,管理員、用戶、測試人員等。
權限:是對某些操作的授權,表示一個使用者能夠執行哪些具體的操作。比如,查看報告、編輯資料等。
在開始之前,請確保你的Spring Boot專案中已經引入了Spring Security的依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
在Spring Security中,可以通過配置用戶的角色和權限來實現安全控制
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN")
            .and()
            .withUser("user").password(passwordEncoder().encode("userPass")).roles("USER");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .anyRequest().authenticated()
            .and().formLogin();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
在這個配置中,我們創建了兩個用戶:admin和user,並分別賦予了ADMIN和USER角色
在現實世界的應用中,權限通常是具體到特定行為的。我們需要擴展上面的例子來支持更細緻的權限控制。這可以通過自定義的權限授權來實現
@RestController
public class DemoController {
    @GetMapping("/admin/dashboard")
    @PreAuthorize("hasAuthority('ADMIN_READ')") // 需求ADMIN_READ權限
    public String adminDashboard() {
        return "Admin Dashboard";
    }
    @GetMapping("/user/profile")
    @PreAuthorize("hasAuthority('USER_READ')") // 需求USER_READ權限
    public String userProfile() {
        return "User Profile";
    }
}
在用戶認證的地方,我們可以增加更多的權限來創建複雜的授權行為
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("admin").password(passwordEncoder().encode("adminPass"))
        .authorities("ADMIN_READ", "ADMIN_WRITE")
        .and()
        .withUser("user").password(passwordEncoder().encode("userPass"))
        .authorities("USER_READ", "USER_WRITE");
}
上面的配置讓admin擁有ADMIN_READ和ADMIN_WRITE這兩個權限,而user擁有USER_READ和USER_WRITE
啟動應用並試著訪問不同的端點。如果使用者未被授予足夠的權限,Spring Security將自動拒絕存取並返回401 Unauthorized或403 Forbidden的回應。
除了在內存中配置用戶,Spring Security還支持從數據庫中載入用戶和權限。你可以通過UserDetailsService接口來實現
利用Spring Security,我們能夠實現細緻的角色與權限管理。透過簡單的配置,並且結合自定義權限,我們可以根據實際需求來控制用戶的存取。這種靈活性讓我們可以滿足各種複雜的安全需求,保護應用程式的安全性